﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Web.Mvc;
using XRM.ActiveDirectoryService;
using XRM.Security.DataAccess;
using XRM.Security.DataAccess.Models;
using XRM.Security.DataAccess.Repositories.Impl;
using XRM.Security.DataAccess.Enums;
using XRM.Security.WebUI.Enums;
using XRM.Security.WebUI.Models.Common;
using XRM.Security.WebUI.Models.UserHistory;
using XRM.Security.WebUI.Models.UserRegister;
using XRM.Security.WebUI.Security;
using XRM.Security.WebUI.Services;
using XRM.Security.WebUI.Consts;
using XRM.Security.WebUI.Models.CertRegister;
using XRM.Security.WebUI.Models.UserSkzi;

namespace XRM.Security.WebUI.Controllers
{
    public class BaseController : Controller
    {
        private const int HistoryPageSize = 10;

        public UserPrincipal UserPrincipal
        {
            get { return UserPrincipal.Current; }
        }

        #region Services

        private IActiveDirectoryService _activeDirectoryService;
        public IActiveDirectoryService ActiveDirectoryService
        {
            get
            {
                if (_activeDirectoryService == null)
                {
                    if ((ConfigurationManager.AppSettings["UseFakeAD"] == null) || (!Convert.ToBoolean(ConfigurationManager.AppSettings["UseFakeAD"])))
                        _activeDirectoryService = new ADService();
                    else
                        _activeDirectoryService = new FakeADService();
                }
                return _activeDirectoryService;
            }
        }

        private IDataManager _dataManager;
        public IDataManager DataManager
        {
            get
            {
                return _dataManager ?? ( _dataManager = new DataManager() );
            }
        }

        private HistoryService _historyService;
        public HistoryService HistoryService
        {
            get
            {
                return _historyService ?? ( _historyService = new HistoryService(DataManager, UserPrincipal.UserId) );
            }
        }

        #endregion

        //todo: перенести репозитории в DataManager
        #region Repositories

        private InfoSystemRepository infoSystemRepository;
        private InfoSystemFileRepository infoSystemFileRepository;
        private IdentityCenterRepository identityCenterRepository;
        private IdentityCenterCertRepository identityCenterCertRepository;
        private IdentityCenterInfoSystemRepository identityCenterInfoSystemRepository;

        private RoleMemberRepository roleMemberRepository;

        private SertificateFsbRepository sertificateFsbRepository;
        private SertificateFstkRepository sertificateFstkRepository;
        private WorkKindSpecRepository workKindSpecRepository;

        private CertRegisterInfoSystemRepository certRegisterInfoSystemRepository;

        private UserInfoSystemRepository userInfoSystemRepository;
        
        private RequestWorkKindParamSpecRepository requestWorkKindParamSpecRepository;
        private RequestCertRepository requestCertRepository;
        private RequestCertInfoSystemRepository requestCertInfoSystemRepository;
        

        protected SystemUserRepository SystemUserRepository
        {
            get { return DataManager.SystemUserRepository; }
        }

        protected RoleMemberRepository RoleMemberRepository
        {
            get { return roleMemberRepository ?? (roleMemberRepository = new RoleMemberRepository()); }
        }

        public DepartmentRepository DepartmentRepository
        {
            get { return DataManager.DepartmentRepository; }
        }

        public DepartmentAddressRepository DepartmentAddressRepository
        {
            get { return DataManager.DepartmentAddressRepository; }
        }

        protected SkziKindRepository SkziKindRepository
        {
            get { return DataManager.SkziKindRepository; }
        }

        protected SertificateFsbRepository SertificateFsbRepository
        {
            get { return sertificateFsbRepository ?? (sertificateFsbRepository = new SertificateFsbRepository()); }
            set { sertificateFsbRepository = value; }
        }

        protected SertificateFstkRepository SertificateFstkRepository
        {
            get { return sertificateFstkRepository ?? (sertificateFstkRepository = new SertificateFstkRepository()); }
            set { sertificateFstkRepository = value; }
        }

        protected InfoSystemRepository InfoSystemRepository
        {
            get { return infoSystemRepository ?? (infoSystemRepository = new InfoSystemRepository()); }
            set { infoSystemRepository = value; }
        }

        protected InfoSystemFileRepository InfoSystemFileRepository
        {
            get { return infoSystemFileRepository ?? (infoSystemFileRepository = new InfoSystemFileRepository()); }
            set { infoSystemFileRepository = value; }
        }

        protected IdentityCenterRepository IdentityCenterRepository
        {
            get { return identityCenterRepository ?? (identityCenterRepository = new IdentityCenterRepository()); }
            set { identityCenterRepository = value; }
        }

        protected IdentityCenterCertRepository IdentityCenterCertRepository
        {
            get { return identityCenterCertRepository ?? (identityCenterCertRepository = new IdentityCenterCertRepository()); }
            set { identityCenterCertRepository = value; }
        }

        protected IdentityCenterInfoSystemRepository IdentityCenterInfoSystemRepository
        {
            get { return identityCenterInfoSystemRepository ?? (identityCenterInfoSystemRepository = new IdentityCenterInfoSystemRepository()); }
            set { identityCenterInfoSystemRepository = value; }
        }

        public WorkKindRepository WorkKindRepository
        {
            get { return DataManager.WorkKindRepository; }
        }

        protected WorkKindParamRepository WorkKindParamRepository
        {
            get { return DataManager.WorkKindParamRepository; }
        }

        protected WorkKindSpecRepository WorkKindSpecRepository
        {
            get { return workKindSpecRepository ?? (workKindSpecRepository = new WorkKindSpecRepository()); }
            set { workKindSpecRepository = value; }
        }

        protected CertRegisterRepository CertRegisterRepository
        {
            get { return DataManager.CertRegisterRepository; }
        }

        protected CertRegisterInfoSystemRepository CertRegisterInfoSystemRepository
        {
            get { return certRegisterInfoSystemRepository ?? (certRegisterInfoSystemRepository = new CertRegisterInfoSystemRepository()); }
            set { certRegisterInfoSystemRepository = value; }
        }

        public UserRegisterRepository UserRegisterRepository
        {
            get { return DataManager.UserRegisterRepository; }
        }

        public PCRepository PCRepository
        {
            get { return DataManager.PCRepository; }
        }

        protected PCStickerRepository PCStickerRepository
        {
            get { return DataManager.PCStickerRepository; }
        }

        protected UserPCRepository UserPCRepository
        {
            get { return DataManager.UserPCRepository; }
        }

        protected UserSkziRepository UserSkziRepository
        {
            get { return DataManager.UserSkziRepository; }
        }

        protected UserHistoryRepository UserHistoryRepository
        {
            get { return DataManager.UserHistoryRepository; }
        }

        protected UserInfoSystemRepository UserInfoSystemRepository
        {
            get { return userInfoSystemRepository ?? (userInfoSystemRepository = new UserInfoSystemRepository()); }
            set { userInfoSystemRepository = value; }
        }

        protected RequestRepository RequestRepository
        {
            get { return DataManager.RequestRepository; }
        }

        protected RequestWorkKindRepository RequestWorkKindRepository
        {
            get { return DataManager.RequestWorkKindRepository; }
        }
        protected RequestWorkKindParamRepository RequestWorkKindParamRepository
        {
            get { return DataManager.RequestWorkKindParamRepository; }
        }
        protected RequestWorkKindParamSpecRepository RequestWorkKindParamSpecRepository
        {
            get { return requestWorkKindParamSpecRepository ?? (requestWorkKindParamSpecRepository = new RequestWorkKindParamSpecRepository()); }
            set { requestWorkKindParamSpecRepository = value; }
        }
        protected RequestCertRepository RequestCertRepository
        {
            get { return requestCertRepository ?? (requestCertRepository = new RequestCertRepository()); }
            set { requestCertRepository = value; }
        }

        protected RequestCertInfoSystemRepository RequestCertInfoSystemRepository
        {
            get { return requestCertInfoSystemRepository ?? (requestCertInfoSystemRepository = new RequestCertInfoSystemRepository()); }
            set { requestCertInfoSystemRepository = value; }
        }
        #endregion

        protected string GetModelErrors()
        {
            var errors = (from modelState in ViewData.ModelState.Values
                          from error in modelState.Errors
                          select error.ErrorMessage).ToList();

            return string.Join("<br />", errors);
        }

        public void ShowAlert(AlertType type, string message)
        {
            TempData["AlertType"] = type;
            TempData["AlertMessage"] = message;
        }

        public void HideAlert()
        {
            TempData["AlertType"] = null;
            TempData["AlertMessage"] = null;
        }

        protected string FilesFolder
        {
            get
            {
                return Server.MapPath("~/Files");
            }
        }

        [NonAction]
        protected FileStreamResult DownloadFile(string path)
        {
            byte[] fileData = System.IO.File.ReadAllBytes(path);
            Stream fileStream = new MemoryStream(fileData);

            FileStreamResult fsr = new FileStreamResult(fileStream, "application/octet-stream");
            fsr.FileDownloadName = Path.GetFileName(path);
            return fsr;
        }

        [NonAction]
        private UserHistoryModel GetNewHistory(int userRegisterId, UserHistoryGroup historyGroup)
        {
            return GetNewHistory(userRegisterId, (int?)null, historyGroup);
        }

        [NonAction]
        private UserHistoryModel GetNewHistory(int userRegisterId, int? requestId, UserHistoryGroup historyGroup)
        {
            UserHistoryModel model = new UserHistoryModel();
            model.UserRegisterId = userRegisterId;
            model.GetUserRegister(UserRegisterRepository.Get(model.UserRegisterId));
                        
            if (requestId.HasValue)
            {
                model.RequestId = requestId;
                model.GetRequest(RequestRepository.Get(requestId.Value));
                model.SystemUserId = model.Request.SystemUserId;
            }
            else
                model.SystemUserId = UserPrincipal.UserId;
            model.GetSystemUser(SystemUserRepository.Get(model.SystemUserId));

            model.HistoryGroup = historyGroup;
            return model;
        }
        
        [NonAction]
        protected void AddUserHistory(UserRegisterModel oldUser, UserRegisterModel newUser, int? requestId)
        {
            UserHistoryModel model = GetNewHistory(newUser.Id.Value, requestId, UserHistoryGroup.Contact);
            
            if (oldUser.LastName != newUser.LastName)
            {
                model.SmallText = string.Format(HistoryTemplate.LastNameChange, oldUser.LastName, newUser.LastName);
                AddUserHistory(model);
            }

            if (oldUser.FirstName != newUser.FirstName)
            {
                model.SmallText = string.Format(HistoryTemplate.FirstNameChange, oldUser.FirstName, newUser.FirstName);
                AddUserHistory(model);
            }

            if (string.IsNullOrEmpty(oldUser.MotherName) && !string.IsNullOrEmpty(newUser.MotherName))
            {
                model.SmallText = string.Format(HistoryTemplate.MotherNameAdd, newUser.MotherName);
                AddUserHistory(model);
            }
            else if (!string.IsNullOrEmpty(oldUser.MotherName) && string.IsNullOrEmpty(newUser.MotherName))
            {
                model.SmallText = string.Format(HistoryTemplate.MotherNameDel, oldUser.MotherName);
                AddUserHistory(model);
            }
            else if (oldUser.MotherName != newUser.MotherName)
            {
                model.SmallText = string.Format(HistoryTemplate.MotherNameChange, oldUser.MotherName, newUser.MotherName);
                AddUserHistory(model);
            }

            if (string.IsNullOrEmpty(oldUser.Post) && !string.IsNullOrEmpty(newUser.Post))
            {
                model.SmallText = string.Format(HistoryTemplate.PostAdd, newUser.Post);
                AddUserHistory(model);
            }
            else if (!string.IsNullOrEmpty(oldUser.Post) && string.IsNullOrEmpty(newUser.Post))
            {
                model.SmallText = string.Format(HistoryTemplate.PostDel, oldUser.Post);
                AddUserHistory(model);
            }
            else if (oldUser.Post != newUser.Post)
            {
                model.SmallText = string.Format(HistoryTemplate.PostChange, oldUser.Post, newUser.Post);
                AddUserHistory(model);
            }

            if (string.IsNullOrEmpty(oldUser.Account) && !string.IsNullOrEmpty(newUser.Account))
            {
                model.SmallText = string.Format(HistoryTemplate.AccountAdd, newUser.Account);
                AddUserHistory(model);
            }
            else if (!string.IsNullOrEmpty(oldUser.Account) && string.IsNullOrEmpty(newUser.Account))
            {
                model.SmallText = string.Format(HistoryTemplate.AccountDel, oldUser.Account);
                AddUserHistory(model);
            }
            else if (oldUser.Account != newUser.Account)
            {
                model.SmallText = string.Format(HistoryTemplate.AccountChange, oldUser.Account, newUser.Account);
                AddUserHistory(model);
            }
            
            if ((!oldUser.DepartmentId.HasValue) && (newUser.DepartmentId.HasValue))
            {
                model.SmallText = string.Format(HistoryTemplate.DepartmentAdd, DepartmentRepository.Get(newUser.DepartmentId).Name);
                AddUserHistory(model);
            }
            else if ((oldUser.DepartmentId.HasValue) && (!newUser.DepartmentId.HasValue))
            {
                model.SmallText = string.Format(HistoryTemplate.DepartmentDel, DepartmentRepository.Get(oldUser.DepartmentId).Name);
                AddUserHistory(model);
            }
            else if (oldUser.DepartmentId != newUser.DepartmentId)
            {
                string oldName = DepartmentRepository.Get(oldUser.DepartmentId).Name;
                string newName = DepartmentRepository.Get(newUser.DepartmentId).Name;
                model.SmallText = string.Format(HistoryTemplate.DepartmentChange, oldName, newName);
                AddUserHistory(model);
            }

            if ((!oldUser.DepartmentAddressId.HasValue) && (newUser.DepartmentAddressId.HasValue))
            {
                model.SmallText = string.Format(HistoryTemplate.DepartmentAddressAdd, DepartmentAddressRepository.Get(newUser.DepartmentAddressId).Address);
                AddUserHistory(model);
            }
            else if ((oldUser.DepartmentAddressId.HasValue) && (!newUser.DepartmentAddressId.HasValue))
            {
                model.SmallText = string.Format(HistoryTemplate.DepartmentAddressDel, DepartmentAddressRepository.Get(oldUser.DepartmentAddressId).Address);
                AddUserHistory(model);
            }
            else if (oldUser.DepartmentAddressId != newUser.DepartmentAddressId)
            {
                string oldName = DepartmentAddressRepository.Get(oldUser.DepartmentAddressId).Address;
                string newName = DepartmentAddressRepository.Get(newUser.DepartmentAddressId).Address;
                model.SmallText = string.Format(HistoryTemplate.DepartmentAddressChange, oldName, newName);
                AddUserHistory(model);
            }

            if (oldUser.Status != newUser.Status)
            {
                string oldName = oldUser.Status.Description();
                string newName = newUser.Status.Description();
                model.SmallText = string.Format(HistoryTemplate.StatusChange, oldName, newName);
                AddUserHistory(model);
            }
        }
        
        [NonAction]
        protected void AddUserHistory_AddPC(int userRegisterId, int pcId, List<string> stickerList, int? requestId)
        {
            UserHistoryModel model = GetNewHistory(userRegisterId, requestId, UserHistoryGroup.Scsi);
            string serialNumber = PCRepository.Get(pcId).SerialNumber;

            model.SmallText = string.Format(HistoryTemplate.PCAdd, serialNumber);
            AddUserHistory(model);

            if (stickerList != null)
                foreach(string item in stickerList)
                {
                    model.SmallText = string.Format(HistoryTemplate.PCStickerAdd, item, serialNumber);
                    AddUserHistory(model);
                }
        }

        protected void AddUserHistory_AddStickers(int userRegisterId, int pcId, List<string> stickerList, int? requestId)
        {
            UserHistoryModel model = GetNewHistory(userRegisterId, requestId, UserHistoryGroup.Scsi);
            string serialNumber = PCRepository.Get(pcId).SerialNumber;

            foreach (string item in stickerList)
            {
                model.SmallText = string.Format(HistoryTemplate.PCStickerAdd, item, serialNumber);
                AddUserHistory(model);
            }
        }

        [NonAction]
        protected void AddUserHistory_AddInfoSystem(int userRegisterId, int isId, int? requestId)
        {
            UserHistoryModel model = GetNewHistory(userRegisterId, requestId, UserHistoryGroup.InfoSystem);
            string name = InfoSystemRepository.Get(isId).InfoSystemName;
            model.SmallText = string.Format(HistoryTemplate.InfoSystemAdd, name);
            AddUserHistory(model);
        }

        [NonAction]
        protected void AddUserHistory_DelInfoSystem(int userRegisterId, int isId)
        {
            UserHistoryModel model = GetNewHistory(userRegisterId, UserHistoryGroup.InfoSystem);
            string name = InfoSystemRepository.Get(isId).InfoSystemName;
            model.SmallText = string.Format(HistoryTemplate.InfoSystemDel, name);
            AddUserHistory(model);
        }
        
        [NonAction]
        protected void AddUserHistory_AddScsi(int userSkziId, int? requestId)
        {
            UserSkzi userSkzi = UserSkziRepository.Get(userSkziId);

            UserHistoryModel model = GetNewHistory(userSkzi.UserRegisterId, requestId, UserHistoryGroup.Scsi);
            model.SmallText = string.Format(HistoryTemplate.ScsiAdd, userSkzi.CopyNumber);
            AddUserHistory(model);
        }

        [NonAction]
        protected void AddUserHistory_EditScsi(UserSkziModel oldUserSkzi, UserSkziModel newUserSkzi)
        {
            UserHistoryModel model = GetNewHistory(oldUserSkzi.UserRegisterId.Value, UserHistoryGroup.Scsi);

            if (oldUserSkzi.CopyNumber != newUserSkzi.CopyNumber)
            {
                model.SmallText = string.Format(HistoryTemplate.ScsiNumChange, oldUserSkzi.CopyNumber, oldUserSkzi.CopyNumber, newUserSkzi.CopyNumber);
                AddUserHistory(model);
            }

            if (oldUserSkzi.PCId.Value != newUserSkzi.PCId.Value)
            {
                oldUserSkzi.PCSerialNumber = PCRepository.Get(oldUserSkzi.PCId.Value).SerialNumber;
                newUserSkzi.PCSerialNumber = PCRepository.Get(newUserSkzi.PCId.Value).SerialNumber;

                model.SmallText = string.Format(HistoryTemplate.ScsiPCChange, oldUserSkzi.CopyNumber, oldUserSkzi.PCSerialNumber, newUserSkzi.PCSerialNumber);
                AddUserHistory(model);
            }

            if (oldUserSkzi.SkziKindId.Value != newUserSkzi.SkziKindId.Value)
            {
                oldUserSkzi.SkziKindName = SkziKindRepository.Get(oldUserSkzi.SkziKindId.Value).ShortName;
                newUserSkzi.SkziKindName = SkziKindRepository.Get(newUserSkzi.SkziKindId.Value).ShortName;

                model.SmallText = string.Format(HistoryTemplate.ScsiKindChange, oldUserSkzi.CopyNumber, oldUserSkzi.SkziKindName, newUserSkzi.SkziKindName);
                AddUserHistory(model);
            }
        }

        [NonAction]
        protected void AddUserHistory_DelScsi(int userSkziId, int? requestId)
        {
            UserSkzi userSkzi = UserSkziRepository.Get(userSkziId);
            UserHistoryModel model = GetNewHistory(userSkzi.UserRegisterId, requestId, UserHistoryGroup.Scsi);
            model.SmallText = string.Format(HistoryTemplate.ScsiDel, userSkzi.CopyNumber);
            AddUserHistory(model);
        }

        [NonAction]
        protected void AddCertHistory(CertRegisterModel oldCert, CertRegisterModel newCert, int? requestId)
        {
            if (!newCert.UserRegisterId.HasValue)
                return;

            UserHistoryModel model = GetNewHistory(newCert.UserRegisterId.Value, requestId, UserHistoryGroup.Cert);

            if (oldCert == null)
            {
                model.SmallText = string.Format(HistoryTemplate.CertAdd, newCert.SerialNumber);
                AddUserHistory(model);
            }
            else
            {
                if ((!string.IsNullOrEmpty(oldCert.SerialNumberEtoken)) && (!string.IsNullOrEmpty(newCert.SerialNumberEtoken)) && (oldCert.SerialNumberEtoken != newCert.SerialNumberEtoken))
                {
                    model.SmallText = string.Format(HistoryTemplate.CertSerialNumberEtokenChange, newCert.SerialNumber, oldCert.SerialNumberEtoken, newCert.SerialNumberEtoken);
                    AddUserHistory(model);
                }
                else if ((string.IsNullOrEmpty(oldCert.SerialNumberEtoken)) && (!string.IsNullOrEmpty(newCert.SerialNumberEtoken)))
                {
                    model.SmallText = string.Format(HistoryTemplate.CertSerialNumberEtokenAdd, newCert.SerialNumber, newCert.SerialNumberEtoken);
                    AddUserHistory(model);
                }
                else if ((!string.IsNullOrEmpty(oldCert.SerialNumberEtoken)) && (string.IsNullOrEmpty(newCert.SerialNumberEtoken)))
                {
                    model.SmallText = string.Format(HistoryTemplate.CertSerialNumberEtokenDel, newCert.SerialNumber, oldCert.SerialNumberEtoken);
                    AddUserHistory(model);
                }

                if ((oldCert.PCId.HasValue) && (oldCert.PCId.Value > 0))
                    oldCert.PCSerialNumber = PCRepository.Get(oldCert.PCId.Value).SerialNumber;
                if ((newCert.PCId.HasValue) && (newCert.PCId.Value > 0))
                    newCert.PCSerialNumber = PCRepository.Get(newCert.PCId.Value).SerialNumber;

                if (oldCert.PCId.HasValue && oldCert.PCId.Value > 0 &&
                    newCert.PCId.HasValue && newCert.PCId.Value > 0 &&
                    oldCert.PCId.Value != newCert.PCId.Value)
                {
                    model.SmallText = string.Format(HistoryTemplate.CertPCChange, newCert.SerialNumber, oldCert.PCSerialNumber, newCert.PCSerialNumber);
                    AddUserHistory(model);
                }
                else if ((!oldCert.PCId.HasValue || oldCert.PCId.Value <= 0) &&
                    newCert.PCId.HasValue && newCert.PCId.Value > 0)
                {
                    model.SmallText = string.Format(HistoryTemplate.CertPCAdd, newCert.SerialNumber, newCert.PCSerialNumber);
                    AddUserHistory(model);
                }
                else if (oldCert.PCId.HasValue && oldCert.PCId.Value > 0 &&
                    (!newCert.PCId.HasValue || newCert.PCId.Value <= 0))
                {
                    model.SmallText = string.Format(HistoryTemplate.CertPCDel, newCert.SerialNumber, oldCert.PCSerialNumber);
                    AddUserHistory(model);
                }

                List<int> listIS = oldCert.SelectedInfoSystems.Where(x => !newCert.SelectedInfoSystems.Any(x2 => x2 == x)).ToList();
                foreach (int item in listIS)
                {
                    InfoSystem dbItem = InfoSystemRepository.Get(item);
                    model.SmallText = string.Format(HistoryTemplate.CertInfoSystemDel, newCert.SerialNumber, dbItem.InfoSystemName);
                    AddUserHistory(model);
                }
                listIS = newCert.SelectedInfoSystems.Where(x => !oldCert.SelectedInfoSystems.Any(x2 => x2 == x)).ToList();
                foreach (int item in listIS)
                {
                    InfoSystem dbItem = InfoSystemRepository.Get(item);
                    model.SmallText = string.Format(HistoryTemplate.CertInfoSystemAdd, newCert.SerialNumber, dbItem.InfoSystemName);
                    AddUserHistory(model);
                }

            }
        }

        [NonAction]
        protected void AddUserHistory(UserHistoryModel model)
        {
            UserHistory dbItem = new UserHistory();
            dbItem.HistoryDate = DateTime.Now;
            dbItem.HistoryText = model.HistoryText;
            dbItem.RequestId = model.RequestId;
            dbItem.SystemUserId = model.SystemUserId;
            dbItem.UserRegisterId = model.UserRegisterId;
            dbItem.HistoryGroup = (int)model.HistoryGroup;
            UserHistoryRepository.Add(dbItem);
        }
        
        [NonAction]
        protected void UserRegister_GrantInfoSystem(int userRegisterId, int isId, int? requestId)
        {
            UserInfoSystem dbItem = new UserInfoSystem();
            dbItem.UserRegisterId = userRegisterId;
            dbItem.InfoSystemId = isId;
            dbItem.GrantDate = DateTime.Now;
            dbItem.GrantSystemUserId = UserPrincipal.UserId;
            UserInfoSystemRepository.Add(dbItem);
            AddUserHistory_AddInfoSystem(dbItem.UserRegisterId, dbItem.InfoSystemId, requestId);
        }

        public ActionResult RedirectWithHash( string url, string hash )
        {
            return Redirect( String.Format( "{0}#{1}", url, hash ) );
        }

        protected JsonResult JsonError( string message )
        {
            return Json( new {isSuccess = false, error = message});
        }

        [System.Web.Mvc.NonAction]
        protected void WriteToCertRegisterFromRequest(RequestCert requestCert, int requestId)
        {
            CertRegister certRegister = new CertRegister();
            certRegister.UploadDate = DateTime.Now;
            certRegister.FileName = requestCert.FileName;
            certRegister.FromDate = requestCert.FromDate;
            certRegister.ToDate = requestCert.ToDate;
            certRegister.IdentityCenterId = requestCert.IdentityCenterId;
            certRegister.SerialNumber = requestCert.SerialNumber;
            certRegister.SerialNumberEtoken = requestCert.SerialNumberEtoken;
            certRegister.Thumbprint = requestCert.Thumbprint;
            certRegister.FileData = requestCert.FileData;
            certRegister.UserRegisterId = requestCert.UserRegisterId;
            certRegister.PCId = requestCert.PCId;
            certRegister.RequestId = requestId;
            requestCert.RequestCertInfoSystems.ToList().ForEach(x => certRegister.CertRegisterInfoSystems.Add(new CertRegisterInfoSystem() { InfoSystemId = x.InfoSystemId }));
            CertRegisterRepository.Add(certRegister);
            AddCertHistory(null, new CertRegisterModel(certRegister), requestId);
        }

        [System.Web.Mvc.NonAction]
        protected void WriteToRequestFromCertRegister(CertRegister certRegister)
        {
            // Пытаемся найти заявку: вид работ = Выпуск сертификата, на того же юзера, не закрыта (без сертификата)
            var reqWork = RequestWorkKindRepository.GetAll(x => (x.WorkKind.CustomId == (int)WorkKindCode.CertCreate) &&
                                                                    (x.Request.UserRegisterId == certRegister.UserRegisterId) &&
                                                                    (!x.CloseDate.HasValue) &&
                                                                    (x.Request.Status != (int)RequestStatus.Error) && x.Request.SystemUserId == UserPrincipal.UserId)
                                                                    .FirstOrDefault();
            if ( reqWork == null )
                return;

            var paramStatusDoc = reqWork.RequestWorkKindParams.FirstOrDefault(x => x.WorkKindParam.CustomId == (int)WorkKindParamCode.StatusDoc);

            // Проверяем статус "Документы переданы в УЦ"
            if ((paramStatusDoc == null) || (Convert.ToInt32(paramStatusDoc.ParamValue) != (int)DocStatus.IdentityCenter))
                return;

            var paramCert = reqWork.RequestWorkKindParams.FirstOrDefault( x => x.WorkKindParam.CustomId == (int)WorkKindParamCode.Cert );
            if (paramCert == null)
                return;

            // Ставим статус, добавляем серт, закрываем работу
            if (!paramCert.RequestCertId.HasValue)
            {
                RequestCert requestCert = new RequestCert();

                requestCert.UploadDate = certRegister.UploadDate;
                requestCert.FileName = certRegister.FileName;
                requestCert.FromDate = certRegister.FromDate;
                requestCert.ToDate = certRegister.ToDate;
                requestCert.IdentityCenterId = certRegister.IdentityCenterId;
                requestCert.SerialNumber = certRegister.SerialNumber;
                requestCert.SerialNumberEtoken = certRegister.SerialNumberEtoken;
                requestCert.Thumbprint = certRegister.Thumbprint;
                requestCert.FileData = certRegister.FileData;
                requestCert.UserRegisterId = certRegister.UserRegisterId;
                requestCert.PCId = certRegister.PCId;
                certRegister.CertRegisterInfoSystems.ToList().ForEach(x => requestCert.RequestCertInfoSystems.Add(new RequestCertInfoSystem() { InfoSystemId = x.InfoSystemId }));
                RequestCertRepository.Add(requestCert);

                paramCert.RequestCertId = requestCert.RequestCertId;
            }
            paramStatusDoc.ParamValue = ((int)DocStatus.Installed).ToString();
            reqWork.CloseDate = DateTime.Today;

            RequestWorkKindRepository.Update( reqWork );

            Request itemReq = reqWork.Request;
            if ( itemReq.RequestWorkKinds.Any( x => !x.CloseDate.HasValue ) )
                itemReq.Status = (int)RequestStatus.InPart;
            else
            {
                itemReq.Status = (int)RequestStatus.Closed;
                itemReq.CloseDate = itemReq.RequestWorkKinds.Max(x => x.CloseDate.Value);
            }
            RequestRepository.Update(itemReq);
        }

        protected ActionResult History (UserHistoryGroup historyGroup, int page)
        {
            int count;
            var model = Sag.Utils.Helpers.QueryableExtension.Page( UserHistoryRepository.GetAll( s => s.HistoryGroup == (int)historyGroup ), page, HistoryPageSize,
                s => s.HistoryDate, false, out count )
                .Select(s => new HistoryItem
                    {
                            Date = s.HistoryDate,
                            Text = s.HistoryText,
                            SystemUser = s.SystemUser,
                            UserRegister = s.UserRegister
                    }).ToList();
            return PartialView( "History", model );
        }
    }

    public sealed class UploadCertTempData
    {
        public string FileName { get; set; }
        public X509Certificate2 RootCertificate { get; set; }
        public X509Certificate2 UserCertificate { get; set; }
    }
}
